package com.nft.qz.commons.schedule;

import com.nft.qz.commons.schedule.task.IScheduledTask;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;

/**
 * 定时器模块配置
 *
 * @author 飞哥
 * @date 2023-08-01$ 15:47$
 */
@Slf4j
@Component
public class ScheduleManager {

    @Autowired
    private ThreadPoolTaskScheduler taskScheduler;
    /**
     * 内部正在执行的定义任务缓存
     */
    public Map<String, ScheduleTaskHolder> cache = new ConcurrentHashMap<>();

    @Async
    public String startTask(String key, IScheduledTask scheduledTask, String cron) {
        ScheduledFuture<?> scheduledFuture = taskScheduler.schedule(scheduledTask, new CronTrigger(cron));
        ScheduleTaskHolder taskHolder = new ScheduleTaskHolder(scheduledTask, scheduledFuture);
        cache.put(key, taskHolder);
        log.info("{},启动成功，唯一标识是：{}", scheduledTask.getName(), key);
        return key;
    }

    public void stopTask(String key) {
        if (StringUtils.isBlank(key)) {
            return;
        }
        ScheduleTaskHolder taskHolder = cache.get(key);
        if (StringUtils.isBlank(key)) {
            return;
        }
        ScheduledFuture scheduledFuture = taskHolder.getScheduledFuture();
        boolean cancel = scheduledFuture.cancel(true);
        if (cancel) {
            log.info("{},启动成功，唯一标识是：{}", taskHolder.getScheduledTask().getName(), key);
        } else {
            log.info("{},停止失败，唯一标识是：{}", taskHolder.getScheduledTask().getName(), key);
        }
    }

    public String changeTask(String key, String cron) {
        if (StringUtils.isAnyBlank(key, cron)) {
            throw new RuntimeException("定义任务的唯一标识以及新的执行表达式不能为空");
        }
        ScheduleTaskHolder taskHolder = cache.get(key);
        if (StringUtils.isBlank(key)) {
            throw new RuntimeException(key + "唯一标识不存在");
        }
        stopTask(key);
        return startTask(key,taskHolder.getScheduledTask(), cron);
    }

}
